﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Daphne.GameShared;

namespace GameEngine.MoveGenerators
{
    public class LongKingMoveGenerator: BaseKingMoveGenerator
    {
        /// <summary>
        /// Flag indicating whether the king is jumping after the piece - part of some checkers rules
        /// </summary>
        private bool _kingJumpsAfterPiece = false;

        /// <summary>
        /// Constructor
        /// </summary>
        public LongKingMoveGenerator(bool kingJumpsAfterPiece = false)
        {
            _kingJumpsAfterPiece = kingJumpsAfterPiece;
        }

        /// <summary>
        /// Returns position to move for long-range kings
        /// </summary>
        protected override List<Position> GetKingStepsInDiagonal(Position figurePos, enumDiagonalDir dir)
        {
            List<Position> list = new List<Position>();

            Position testPos = figurePos.GetNextField(dir);
            while (GameBoard.IsOutsideBoard(testPos) == false)
            {
                if (IsPlaceFreeToMove(testPos) == false)
                    return list;
                list.Add(testPos);
                testPos = testPos.GetNextField(dir);
            } // while

            return list;
        }

        /// <summary>
        /// Generates jumps for long-range king in one direction
        /// </summary>
        protected override List<Position> CheckKingJumpsInDirection(Position pos, enumDiagonalDir dir, enumFigureColor clrMovedFigure)
        {
            List<Position> destFields = new List<Position>();
            Position testPos = pos.GetNextField(dir);

            while (GameBoard.IsOutsideBoard(testPos) == false)
            {
                if (IsPlaceFreeToMove(testPos) == false)
                {
                    // figure of the same color?
                    if (GameBoard.GetField(testPos.Row, testPos.Col).FigureColor() == clrMovedFigure)
                        return destFields;
                 
                    // check if next field is free to jump at
                    Position jumpedFigurePos = testPos;
                    testPos = testPos.GetNextField(dir);

                    bool bMultipleJumpFound = false;
                    List<Position> temporaryPos = new List<Position>();
                    List<Position> jumpPos = new List<Position>();
                    while (IsPlaceFreeToMove(testPos))
                    {
                        temporaryPos.Add(testPos);

                        // check if the king can jump after the captured piece
                        // requirement e.g. by South-German Draughts
                        if (_kingJumpsAfterPiece == true)
                        {                                                    
                            return  temporaryPos.ToList();
                        }

                        enumFigureType savedJumpedFIgure = GameBoard.RemoveFigure(jumpedFigurePos);
                        if (EvaluateKingJumps(testPos, clrMovedFigure, dir.Opposite()).Count > 0)
                        {
                            jumpPos.Add(testPos);
                            bMultipleJumpFound = true;
                        }
                        GameBoard.PlaceFigure(jumpedFigurePos, savedJumpedFIgure);

                        testPos = testPos.GetNextField(dir);
                    }

                    if (bMultipleJumpFound == true)
                        destFields.AddRange(jumpPos);
                    else
                        destFields.AddRange(temporaryPos);

                    return destFields;
                } // if

                testPos = testPos.GetNextField(dir);
            }
            // end of board reached, no jumps
            return destFields;
        }

    }
}
